﻿using System;
using System.Linq;
using NUnit.Framework;
using Yala.UnitTests.IocSetup;
using Yala.UnitTests.UnitTestBase;
using Yala.Models.Users;

namespace Yala.UnitTests.Repositories {
    
    [TestFixture]
    public class UsersRepositoryTest : DbUnitTestBase {

        IUsersRepository _repo;
        private const string USER_GUID_STRING = "825cb802-193e-4627-9da3-86ef9acb1205";
        private const string AUTHPROVIDER_GUID_STRING = "485ac802-993e-4627-9da3-86ef9ecb1295";
        private const string DELETE_USER_GUID_STRING = "02ee4e2a-193e-4627-9da3-86ef9acb1205";

        public UsersRepositoryTest() {
            Bootstrapper.ConfigureStructureMap();
        }

        [TestFixtureSetUp]
        public void Init() {
            DatabaseFixtureSetUp();
        }

        [SetUp]
        public void SetUp() {
            DatabaseSetUp();
            _repo = StructureMap.ObjectFactory.GetInstance<IUsersRepository>();
        }

        [TearDown]
        public void TearDown() {
            DatabaseTearDown();
            _repo.Dispose();
        }

        [TestFixtureTearDown]
        public void CleanUp() {
            DatabaseFixtureTearDown();
        }

        [Test]
        public void Can_Get_All_Users() {
            var users = _repo.All();
            Assert.IsNotNull(users);
            Assert.AreEqual(4, users.Count());
        }

        [Test]
        public void Can_Get_User_By_Id() {
            var userId = Guid.Parse(USER_GUID_STRING);
            var user = _repo.Single(x => x.Id == userId);
            Assert.IsNotNull(user);
            Assert.AreEqual(USER_GUID_STRING, user.Id.ToString());
        }

        [Test]
        public void Can_Get_Items_For_A_User() {
            var userId = Guid.Parse(USER_GUID_STRING);
            var user = _repo.Single(x => x.Id == userId);

            Assert.IsNotNull(user.Items);
            Assert.AreEqual(3, user.Items.Count);
        }

        [Test]
        public void Can_Update_User() {
            var userId = Guid.Parse(USER_GUID_STRING);
            var user = _repo.Single(x => x.Id == userId);

            // Update info
            var newEmail = "updatedemail@foo.com";
            user.Email = newEmail;
            _repo.Update(user);

            // Get updated user
            var updatedUser = _repo.Single(x => x.Id == userId);

            Assert.IsNotNull(updatedUser);
            Assert.AreEqual(newEmail, updatedUser.Email);
        }

        [Test]
        public void Can_Get_A_Users_AuthProvider() {
            // Select user where Id match the specify Id
            var userId = Guid.Parse(USER_GUID_STRING);
            var user = _repo.Single(x => x.Id == userId);

            Assert.IsNotNull(user.AuthProvider);
            Assert.AreEqual(Guid.Parse(AUTHPROVIDER_GUID_STRING), user.AuthProvider.Id);
        }

        [Test]
        public void Can_Delete_User_By_Id() {
            // Delete provider given it's Id
            var userId = Guid.Parse(DELETE_USER_GUID_STRING);
            _repo.Delete(x => x.Id == userId);
            _repo.CommitChanges();

            // Now get all providers
             var users = _repo.All();
            
            Assert.IsNotNull(users);
            Assert.AreEqual(3, users.Count());
        }

        [Test]
        public void Can_Delete_User() {
            // Delete provider given it's Id
            var userId = Guid.Parse(DELETE_USER_GUID_STRING);
            var user = _repo.Single(x => x.Id == userId);
            _repo.Delete(user);
            _repo.CommitChanges();

            // Now get all providers
            var users = _repo.All();
            Assert.IsNotNull(users);
            Assert.AreEqual(3, users.Count());
        }
    }
}
